﻿using System.Xml.Linq;

namespace EasyXaf.DynamicForm.Models;

public class Field : FormItem
{
    public string Value { get; set; }

    public object ActualValue { get; set; }

    public string ValueType { get; set; }

    public string Editor { get; set; }

    public bool? Required { get; set; }

    public bool IsCalculated
    {
        get
        {
            var value = Value?.Trim();
            return !string.IsNullOrWhiteSpace(value)
                && value.StartsWith('{')
                && value.EndsWith('}');
        }
    }

    public Locations? CaptionLocation { get; set; }

    public List<Validation> Validations { get; }

    public Field(Form form, Element parent)
        : base(form, parent)
    {
        Validations = [];
    }

    public override void WriteXml(XElement element)
    {
        base.WriteXml(element);

        if (!string.IsNullOrWhiteSpace(Value))
        {
            SetXmlAttributeValue(element, "value", Value);
        }

        if (!string.IsNullOrWhiteSpace(ValueType))
        {
            SetXmlAttributeValue(element, "type", ValueType);
        }

        if (!string.IsNullOrWhiteSpace(Editor))
        {
            SetXmlAttributeValue(element, "editor", Editor);
        }

        if (Required.HasValue)
        {
            SetXmlAttributeValue(element, "required", Required.Value);
        }

        if (CaptionLocation.HasValue)
        {
            SetXmlAttributeValue(element, "caption-location", CaptionLocation switch
            {
                Locations.Left => "left",
                Locations.Top => "top",
                _ => "default",
            });
        }

        var validationsElement = new XElement("validations");
        foreach (var validation in Validations)
        {
            var validationElement = validation.CreateXElement();
            validation.WriteXml(validationElement);
            validationsElement.Add(validationElement);
        }
        element.Add(validationsElement);
    }

    public override void ReadXml(XElement element)
    {
        base.ReadXml(element);

        Value = GetXmlAttributeValue<string>(element, "value");
        ValueType = GetXmlAttributeValue<string>(element, "type");
        Editor = GetXmlAttributeValue<string>(element, "editor");
        Required = GetXmlAttributeValue<bool?>(element, "required");
        CaptionLocation = GetXmlAttributeValue<string>(element, "caption-location") switch
        {
            "left" => Locations.Left,
            "top" => Locations.Top,
            _ => null,
        };

        Validations.Clear();

        foreach (var validationElement in element.Elements("validations"))
        {
            var elementName = validationElement.Name.LocalName;
            if (elementName == "validation")
            {
                var validation = new Validation(this);
                validation.ReadXml(validationElement);
                Validations.Add(validation);
            }
        }
    }

    public override XElement CreateXElement()
    {
        return new XElement("field");
    }
}
